package net.boar.os;

import java.io.DataOutputStream;
import java.io.FileOutputStream;
import java.util.Arrays;
import java.util.List;

/**
 * @Author: zgl
 * @Date: 2021/6/23 11:39
 * @Description:
 */
public class FloppyDiskEntity {
    private static final int CYLINDER_SIZE = 2;
    private static final int TRACK_SIZE = 80;
    private static final int SECTOR_SIZE = 18;
    private static class CylinderEntity{
        /**每个柱面有80个磁道*/
        private TrackEntity[] tracks;

        public CylinderEntity(int tracksSize,int sectorsSize) {
            this.tracks = new TrackEntity[tracksSize];
            for (int i = 0; i < tracks.length; i++) {
                tracks[i] = new TrackEntity(sectorsSize);
            }
        }

        public TrackEntity[] getTracks() {
            return tracks;
        }

        public void setTracks(TrackEntity[] tracks) {
            this.tracks = tracks;
        }
        public void fill(){
            for (int i = 0; i < tracks.length; i++) {
                tracks[i].fill();
            }
        }
    }
    private static class TrackEntity {
        /**每个磁道有18个扇区*/
        private SectorEntity[] sectors;

        public TrackEntity(int sectorsSize) {
            sectors = new SectorEntity[sectorsSize];
            for (int i = 0; i < sectors.length; i++) {
                sectors[i] = new SectorEntity();
            }
        }

        public SectorEntity[] getSectors() {
            return sectors;
        }

        public void setSectors(SectorEntity[] sectors) {
            this.sectors = sectors;
        }
        public void fill(){
            for (int i = 0; i < sectors.length; i++) {
                sectors[i].fill();
            }
        }
    }
    private static class SectorEntity {
        /**每个扇区有512个字节*/
        private byte[] buf = new byte[512];

        public byte[] getBuf() {
            return buf;
        }

        public void setBuf(byte[] buf) {
            this.buf = buf;
        }
        public void fill(){
            Arrays.fill(buf, (byte) 0);
        }
        public void copyTo(byte[] src){
            System.arraycopy(src,0,buf,0,src.length);
        }
    }
    public static class IndexEntity{
        /**磁盘的哪个面 0,1*/
        private int cylinderIndex;
        /**盘面上的哪个磁道*/
        private int trackIndex;
        /**磁道上的哪个扇区*/
        private int sectorIndex;

        public IndexEntity() {
        }

        public IndexEntity(int cylinderIndex, int trackIndex, int sectorIndex) {
            this.cylinderIndex = cylinderIndex;
            this.trackIndex = trackIndex;
            this.sectorIndex = sectorIndex;
        }

        public int getCylinderIndex() {
            return cylinderIndex;
        }

        public void setCylinderIndex(int cylinderIndex) {
            this.cylinderIndex = cylinderIndex;
        }

        public int getTrackIndex() {
            return trackIndex;
        }

        public void setTrackIndex(int trackIndex) {
            this.trackIndex = trackIndex;
        }

        public int getSectorIndex() {
            return sectorIndex;
        }

        public void setSectorIndex(int sectorIndex) {
            this.sectorIndex = sectorIndex;
        }
    }
    /**每个磁盘有两个柱面*/
    private CylinderEntity[] cylinders;
    private IndexEntity index;
    public FloppyDiskEntity() {
        cylinders = new CylinderEntity[CYLINDER_SIZE];
        for (int i = 0; i < cylinders.length; i++) {
            cylinders[i] = new CylinderEntity(TRACK_SIZE,SECTOR_SIZE);
        }
    }
    public void makeFloppy(String fileName){
        try {
            DataOutputStream out = new DataOutputStream(new FileOutputStream(fileName));
            //2
            for (int head = 0; head < CYLINDER_SIZE; head++) {
                //80
                for (int cylinder = 0; cylinder < TRACK_SIZE; cylinder++) {
                    //18
                    for (int sector = 1; sector <= SECTOR_SIZE; sector++) {
                        byte[] buf = readFloppy(head,cylinder,sector);
                        out.write(buf);
                    }
                }
            }
        }catch (Exception e){
            e.printStackTrace();
        }
    }
    private byte[] readFloppy(int cylinderIndex, int trackIndex, int sectorIndex){
        this.index = buildIndex(cylinderIndex,trackIndex,sectorIndex);
        CylinderEntity disk = cylinders[this.index.cylinderIndex];
        TrackEntity cylinder = disk.tracks[this.index.trackIndex];
        SectorEntity sector = cylinder.sectors[this.index.sectorIndex];
        return sector.buf;
    }
    public void writeFloppy(int cylinderIndex, int trackIndex, int sectorIndex, byte[] buff){
        this.index = buildIndex(cylinderIndex,trackIndex,sectorIndex);
        CylinderEntity disk = cylinders[this.index.cylinderIndex];
        TrackEntity cylinder = disk.tracks[this.index.trackIndex];
        SectorEntity sector = cylinder.sectors[this.index.sectorIndex];
        sector.copyTo(buff);
    }
    public static IndexEntity buildIndex(){
        return buildIndex(CYLINDER_SIZE,TRACK_SIZE,SECTOR_SIZE);
    }
    public static IndexEntity buildIndex(int cylinderIndex, int trackIndex, int sectorIndex){
        if(cylinderIndex < 0){
            cylinderIndex = 0;
        }else if(cylinderIndex >= CYLINDER_SIZE){
            cylinderIndex = cylinderIndex - 1;
        }
        if(trackIndex < 0){
            trackIndex = 0;
        }else if(trackIndex >= TRACK_SIZE){
            trackIndex = TRACK_SIZE - 1;
        }
        if(sectorIndex < 0){
            sectorIndex = 0;
        }else if(sectorIndex >= SECTOR_SIZE){
            sectorIndex = SECTOR_SIZE - 1;
        }else {
            sectorIndex -= 1;
        }
        return new IndexEntity(cylinderIndex,trackIndex,sectorIndex);
    }
    public void fill(){
        for (int i = 0; i < cylinders.length; i++) {
            cylinders[i].fill();
        }
    }
}
